package com.newly.common.base.entity.auth;

import com.newly.common.base.constants.AuthConstant;
import com.newly.common.base.exception.AuthException;

import java.util.List;

/**
 * @program: newly-parent
 * @remark: 当前租户
 * @author: guan
 * @create: 2021-12-23 05:16
 */
public interface ICurrentTenant {
    /**
     * @return 获取租户id
     */
    Long getUserId();

    /**
     * @return 获取租户租户名
     */
    String getUsername();

    /**
     * @return 获取租户昵称
     */
    String getNickname();

    /**
     * @return 获取租户类型
     */
    int getType();

    /**
     * 通过类型获取权限实体
     *
     * @param entityType 权限实体类型
     * @return
     */
    List<AuthPayload.AuthEntity> getEntities(AuthConstant.AuthEntityType entityType);

    /**
     * 通过角色id与类型获取权限实体
     *
     * @param entityType 权限实体类型
     * @return
     */
    List<AuthPayload.AuthEntity> getEntities(Integer roleId, AuthConstant.AuthEntityType entityType);

    /**
     * 获取指定的权限实体id，例如获取菜单id，设备id等
     *
     * @param entityType 权限实体类型
     * @return 权限实体id
     */
    List<String> getEntityIds(AuthConstant.AuthEntityType entityType);

    /**
     * 获取指定的权限实体id，例如获取菜单id，设备id等
     *
     * @param entityType 权限实体类型
     * @return 权限实体id
     */
    List<String> getEntityIds(Integer roleId, AuthConstant.AuthEntityType entityType);

    /**
     * 获取所有权限实体id，例如获取菜单id，设备id等
     *
     * @return 权限实体id
     */
    List<String> getEntityIds();

    /**
     * 获取当前租户菜单id
     *
     * @return 菜单id
     */
    List<Integer> getMenuIds();

    /**
     * 获取所有角色id
     *
     * @return 角色id
     */
    List<Integer> getRoleIds();

    /**
     * 获取当前租户角色，（非子角色）
     *
     * @return 角色id
     */
    List<Integer> getSelfRoleIds();

    /**
     * 获取当前租户角色，（非子角色）
     *
     * @return 角色id
     */
    Integer getSelfRoleId();


    //////////////////////// 判断 ////////////////////////

    /**
     * 是否开发者
     *
     * @return 开发者返回true
     */
    boolean isDev();

    /**
     * 当前租户是否具备id为menuIds的菜单
     *
     * @return 具备返回true
     */
    boolean hasMenuIds(List<Integer> menuIds);

    /**
     * 当前租户是否具备id为menuIds的菜单
     *
     * @return 具备返回true
     */
    boolean hasMenuIds(Integer... menuIds);

    /**
     * 当前租户是否具备id为menuId的菜单
     *
     * @return 具备返回true
     */
    boolean hasMenuId(Integer menuId);

    /**
     * 当前租户是否具备id为roleIds的角色
     *
     * @param roleIds 角色id
     * @return 具备返回true
     */
    boolean hasRoles(List<Integer> roleIds);

    /**
     * 当前租户是否具备id为roleIds的角色
     *
     * @param roleIds 角色id
     * @return 具备返回true
     */
    boolean hasRoles(Integer... roleIds);

    /**
     * 当前租户是否具备id为roleId的角色
     *
     * @param roleId 角色id
     * @return 具备返回true
     */
    boolean hasRole(Integer roleId);

    /**
     * 当前租户的角色（非子角色）是否具备id为roleIds的角色
     *
     * @param roleIds 角色id
     * @return 具备返回true
     */
    boolean hasSelfRoles(List<Integer> roleIds);

    /**
     * 当前租户的角色（非子角色）是否具备id为roleIds的角色
     *
     * @param roleIds 角色id
     * @return 具备返回true
     */
    boolean hasSelfRoles(Integer... roleIds);

    /**
     * 当前租户的角色（非子角色）是否具备id为roleId的角色
     *
     * @param roleId 角色id
     * @return 具备返回true
     */
    boolean hasSelfRole(Integer roleId);

    /**
     * 当前租户是否具备权限实体类型为entity并且id为entityIds的权限实体
     *
     * @return 具备返回true
     */
    boolean hasEntities(AuthConstant.AuthEntityType entityType, List<String> entityIds);

    /**
     * 当前租户是否具备权限实体类型为entity并且id为entityId的权限实体
     *
     * @return 具备返回true
     */
    boolean hasEntity(AuthConstant.AuthEntityType entityType, String entityId);


    //////////////////////// 断言 ////////////////////////

    /**
     * 断言是开发者或不是开发者，通过orientation来确定
     *
     * @param orientation 取向
     * @param errMsg      错误消息
     * @return 条件不满足抛出异常，满足返回返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertDev(int orientation, String errMsg) throws AuthException;

    /**
     * 是开发者抛出异常
     *
     * @param errMsg 错误消息
     * @return 当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIsDev(String errMsg) throws AuthException;

    /**
     * 是开发者抛出异常
     *
     * @return 当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIsDev() throws AuthException;

    /**
     * 不是开发者抛出异常
     *
     * @param errMsg 错误消息
     * @return 当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertNoDev(String errMsg) throws AuthException;

    /**
     * 不是开发者抛出异常
     *
     * @return 当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertNoDev() throws AuthException;

    /**
     * 当前租户具备或不具备菜单id为menuIds的菜单
     *
     * @param orientation 取向，具备或不具备
     * @param menuIds     菜单id
     * @param errMsg      错误消息
     * @return 条件不满足抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertMenus(int orientation, List<Integer> menuIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备菜单id为menuIds的菜单
     *
     * @param menuIds 菜单id
     * @return 不具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeMenus(List<Integer> menuIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备菜单id为menuIds的菜单
     *
     * @param menuIds 菜单id
     * @return 不具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeMenus(List<Integer> menuIds) throws AuthException;

    /**
     * 当前租户必须具备菜单id为menuId的菜单
     *
     * @param menuId 菜单id
     * @param errMsg 错误消息
     * @return 不具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeMenu(Integer menuId, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备菜单id为menuId的菜单
     *
     * @param menuId 菜单id
     * @return 不具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeMenu(Integer menuId) throws AuthException;

    /**
     * 当前租户必须不具备菜单id为menuIds的菜单
     *
     * @param menuIds 菜单id
     * @return 具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeMenus(List<Integer> menuIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备菜单id为menuIds的菜单
     *
     * @param menuIds 菜单id
     * @return 具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeMenus(List<Integer> menuIds) throws AuthException;

    /**
     * 当前租户必须不具备菜单id为menuId的菜单
     *
     * @param menuId 菜单id
     * @param errMsg 错误消息
     * @return 具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeMenu(Integer menuId, String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备菜单id为menuId的菜单
     *
     * @param menuId 菜单id
     * @return 具备该菜单抛出异常，满足返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeMenu(Integer menuId) throws AuthException;

    /**
     * 当前租户必须具备或不具备（取决于orientation）角色id为roleIds的角色
     *
     * @param orientation 取向
     * @param roleIds     角色id
     * @param errMsg      错误消息
     * @return 不满足条件抛出异常，满足条件返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertRoles(int orientation, List<Integer> roleIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleIds的角色
     *
     * @param roleIds 角色id
     * @param errMsg  错误消息
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeRoles(List<Integer> roleIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleIds的角色
     *
     * @param roleIds 角色id
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeRoles(List<Integer> roleIds) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleId的角色
     *
     * @param roleId 角色id
     * @param errMsg 错误消息
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeRole(Integer roleId, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleIds的角色
     *
     * @param roleId 角色id
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeRole(Integer roleId) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleIds的角色
     *
     * @param roleIds 角色id
     * @param errMsg  错误消息
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeRoles(List<Integer> roleIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleIds的角色
     *
     * @param roleIds 角色id
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeRoles(List<Integer> roleIds) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleId的角色
     *
     * @param roleId 角色id
     * @param errMsg 错误消息
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeRole(Integer roleId, String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleIds的角色
     *
     * @param roleId 角色id
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeRole(Integer roleId) throws AuthException;


    /**
     * 当前租户必须具备或不具备（取决于orientation）角色id为roleIds的角色（非子角色）
     *
     * @param orientation 取向
     * @param roleIds     角色id
     * @param errMsg      错误消息
     * @return 不满足条件抛出异常，满足条件返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertSelfRoles(int orientation, List<Integer> roleIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleIds的角色（非子角色）
     *
     * @param roleIds 角色id
     * @param errMsg  错误消息
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeSelfRoles(List<Integer> roleIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleIds的角色（非子角色）
     *
     * @param roleIds 角色id
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeSelfRoles(List<Integer> roleIds) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleId的角色（非子角色）
     *
     * @param roleId 角色id
     * @param errMsg 错误消息
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeSelfRole(Integer roleId, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备角色id为roleIds的角色（非子角色）
     *
     * @param roleId 角色id
     * @return 不具备该角色会抛出异常，具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertIncludeSelfRole(Integer roleId) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleIds的角色（非子角色）
     *
     * @param roleIds 角色id
     * @param errMsg  错误消息
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeSelfRoles(List<Integer> roleIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleIds的角色（非子角色）
     *
     * @param roleIds 角色id
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeSelfRoles(List<Integer> roleIds) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleId的角色（非子角色）
     *
     * @param roleId 角色id
     * @param errMsg 错误消息
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeSelfRole(Integer roleId, String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备角色id为roleIds的角色（非子角色）
     *
     * @param roleId 角色id
     * @return 具备该角色会抛出异常，不具备返回当前对象
     * @throws AuthException 断言异常
     */
    ICurrentTenant assertExcludeSelfRole(Integer roleId) throws AuthException;

    /**
     * 当前租户具备或不具备(取决于orientation参数)权限实体类型为permEntity并且id为entityIds的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param orientation    取向
     * @param authEntityType 权限实体类型
     * @param entityIds      权限实体id(例如:设备id,站点id)
     * @param errMsg         错误消息
     * @return 不满足条件抛出异常，满足条件返回当前对象
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertEntities(int orientation, AuthConstant.AuthEntityType authEntityType,
                                  List<String> entityIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备权限实体类型为permEntity并且id为entityIds的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityIds      权限实体id(例如:设备id,站点id)
     * @param errMsg         错误消息
     * @return 具备该权限实体返回当前对象，不具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertIncludeEntities(AuthConstant.AuthEntityType authEntityType, List<String> entityIds, String errMsg) throws AuthException;

    /**
     * 当前租户必须具备权限实体类型为permEntity并且id为entityIds的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityIds      权限实体id(例如:设备id,站点id)
     * @return 具备该权限实体返回当前对象，不具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertIncludeEntities(AuthConstant.AuthEntityType authEntityType, List<String> entityIds) throws AuthException;

    /**
     * 当前租户必须具备权限实体类型为permEntity并且id为entityId的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityId       权限实体id(例如:设备id,站点id)
     * @return 具备该权限实体返回当前对象，不具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertIncludeEntity(AuthConstant.AuthEntityType authEntityType, String entityId,
                                       String errMsg) throws AuthException;

    /**
     * 当前租户必须具备权限实体类型为permEntity并且id为entityId的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityId       权限实体id(例如:设备id,站点id)
     * @return 具备该权限实体返回当前对象，不具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertIncludeEntity(AuthConstant.AuthEntityType authEntityType, String entityId) throws AuthException;

    /**
     * 当前租户必须不具备权限实体类型为permEntity并且id为entityIds的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityIds      权限实体id(例如:设备id,站点id)
     * @return 不具备该权限实体返回当前对象，具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertExcludeEntities(AuthConstant.AuthEntityType authEntityType, List<String> entityIds
            , String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备权限实体类型为permEntity并且id为entityIds的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityIds      权限实体id(例如:设备id,站点id)
     * @return 不具备该权限实体返回当前对象，具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertExcludeEntities(AuthConstant.AuthEntityType authEntityType, List<String> entityIds) throws AuthException;

    /**
     * 当前租户必须不具备权限实体类型为permEntity并且id为entityId的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityId       权限实体id(例如:设备id,站点id)
     * @return 不具备该权限实体返回当前对象，具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertExcludeEntity(AuthConstant.AuthEntityType authEntityType, String entityId,
                                       String errMsg) throws AuthException;

    /**
     * 当前租户必须不具备权限实体类型为permEntity并且id为entityId的权限实体
     * 权限实体： 被权限所管理的实体，例如： 每一个设备，每一个站点
     *
     * @param authEntityType 权限实体类型
     * @param entityId       权限实体id(例如:设备id,站点id)
     * @return 不具备该权限实体返回当前对象，具备抛出异常
     * @throws AuthException 鉴权异常
     */
    ICurrentTenant assertExcludeEntity(AuthConstant.AuthEntityType authEntityType, String entityId) throws AuthException;


}
